﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Radar.Navigation;

namespace Radar.Optimization
{
    internal class Grid
    {

        internal Grid(int columnCount, int rowCount)
        {
            ColumnCount = columnCount;
            RowCount = rowCount;
            Cells = new GridCell[columnCount, rowCount];
        }

        #region Published Methods

        public GridCell GetCellAt(Point point)
        {
            return Cells[GetXIndexFromCoordinate(point.X), GetYIndexFromCoordinate(point.Y)];
        }

        public GridCellRange GetCellsInRectangle(int left, int top, int right, int bottom)
        {
            int x = GetXIndexFromCoordinate(left);
            int y = GetYIndexFromCoordinate(top);

            int width = GetXIndexFromCoordinate(right) - x + 1;
            int height = GetYIndexFromCoordinate(bottom) - y + 1;

            if (width > 0 && height > 0)
            {
                var cells = new GridCell[width, height];
                for (int indexX = 0; indexX < width; indexX++)
                {
                    for (int indexY = 0; indexY < height; indexY++)
                    {
                        cells[indexX, indexY] = Cells[x + indexX, y + indexY];
                    }
                }

                return new GridCellRange(cells);
            }
            else
            {
                return null;
            }
        }

        internal NavZone GetZoneAt(Point point)
        {
            var zones = GetCellAt(point).ZonesTouching;
            var count = zones.Length;
            for (int i = 0; i < count; i++)
            {
                NavZone zone = zones[i];
                if (zone.Left <= point.X && zone.Right > point.X && zone.Top <= point.Y && zone.Bottom > point.Y)
                {
                    return zone;
                }
            }
            return null;
        }

#endregion

        private int GetXIndexFromCoordinate(int x)
        {
            int index = (x - LeftBound) / CellWidth;
            if (index < 0) index = 0;
            if (index >= ColumnCount) index = ColumnCount - 1;
            return index;
        }

        private int GetYIndexFromCoordinate(int y)
        {
            int index = (y - TopBound) / CellHeight;
            if (index < 0) index = 0;
            if (index >= RowCount) index = RowCount - 1;
            return index;
        }

        internal GridCell[,] Cells;

        internal int LeftBound;
        internal int TopBound;
        internal int RightBound;
        internal int BottomBound;

        internal int CellWidth;
        internal int CellHeight;

        internal int ColumnCount;
        internal int RowCount;

    }
}
